<template>
  <el-dialog v-model="visible" :title="title + getTitle" width="50%">
    <el-form ref="formRef" label-width="120px" :model="form" :rules="rules">
      <el-row :gutter="0">
        <el-col v-for="column in addParams" :key="column.prop" :span="column.colSpan ?? 24">
          <el-form-item :label="column.label" :prop="column.prop">
            <component
              :is="getComponent(column.component)"
              v-model="form[column.prop]"
              :disabled="column.disabled"
              :multiple="column.multiple"
              :options="optionsMap[column.prop] || column.options"
              :placeholder="column.placeholder"
              :type="getType(column)"
              :url="column.url"
              :value-format="column.component === 'date-picker' || column.component === 'time-picker' ? 'YYYY-MM-DD HH:mm:ss' : undefined"
              @visible-change="handleVisibleChange(column.prop, column.optionsPath)"
            />
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="closeDialog">取消</el-button>
        <el-button type="primary" @click="submitForm">确定</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
import { ElOption, ElSelect } from 'element-plus'
import { computed, defineEmits, defineProps, ref, watch } from 'vue'
import Public from '~/src/api/public'
import { type ComponentType, getComponent as getComponentFromMap, getComponentType } from '../componentMap'

const props = defineProps<{
  modelValue: boolean
  addParams: Array<{
    prop: string
    rule?: string
    url: string
    label: string
    component: ComponentType
    options?: Array<{ label: string; value: any }>
    multiple?: boolean
    default?: any
    required?: boolean
    placeholder?: string
    colSpan?: number
    disabled?: boolean
    optionsPath?: any
  }>
  moduleName: string
  title: string
  formData: any
}>()

const emit = defineEmits<{
  (e: 'update:modelValue', value: boolean): void
  (e: 'submit', formData: any): void
}>()

const visible = ref(props.modelValue)

watch(
  () => props.modelValue,
  (newValue) => {
    visible.value = newValue
    if (!newValue) {
      resetForm()
    }
    console.log('props.modelValue changed to:', newValue) // 增加调试打印
  }
)

watch(visible, (newValue) => {
  console.log('visible changed to:', newValue) // 增加调试打印
  emit('update:modelValue', newValue)
})

const form = ref<FormType>({})

watch(
  () => props.formData,
  (newFormData) => {
    form.value = { ...newFormData }
    console.log('props.formData changed to:', newFormData) // 增加调试打印
  },
  { immediate: true }
)

watch(
  () => props.addParams,
  (newColumns) => {
    form.value = newColumns.reduce((acc, addParam) => {
      acc[addParam.prop] = addParam.default ?? null
      return acc
    }, {} as FormType)
    console.log('props.addParams changed to:', newColumns) // 增加调试打印
  },
  { immediate: true }
)

interface ApiResponse<T> {
  code: number
  result: T
}

// 声明一个变量来存储 options
const optionsMap = ref<Record<string, Array<{ label: string; value: any }>>>({})

const fetchOptions = async (prop: string, optionsPath: string) => {
  try {
    const response = (await Public.getDropDownListApi({ url: optionsPath })) as unknown as ApiResponse<{ id: any; roomName: any }[]>
    const options = response.result.map((item: { id: any; roomName: any }) => ({
      value: item.id,
      label: item.roomName,
    }))
    optionsMap.value[prop] = options // 更新 optionsMap
    console.log(`Fetched options for ${prop}:`, options) // 增加调试打印
  } catch (error) {
    console.error(`Failed to fetch options for ${prop}:`, error)
  }
}

const handleVisibleChange = (prop: string, optionsPath: string) => {
  if (optionsPath && !optionsMap.value[prop]) {
    fetchOptions(prop, optionsPath)
  }
}

interface FormType {
  [key: string]: any
}

const formRef = ref<any>(null)

const resetForm = () => {
  form.value = {}
  console.log('Form reset:', form.value) // 增加调试打印
}

const getTitle = computed(() => {
  return `${props.moduleName}`
})

const ElSelectWithOptions = {
  components: { ElSelect, ElOption },
  props: ['modelValue', 'options', 'multiple', 'placeholder'],
  emits: ['update:modelValue', 'visible-change'],
  template: `
    <el-select :model-value="modelValue" @update:model-value="$emit('update:modelValue', $event)" :multiple="multiple" :placeholder="placeholder" @visible-change="$emit('visible-change', $event)">
      <el-option
        v-for="option in options"
        :key="option.value"
        :label="option.label"
        :value="option.value"
      />
    </el-select>
  `,
}

// 获取组件
const getComponent = (type: ComponentType) => {
  return getComponentFromMap(type)
}

// 获取组件类型
const getType = (column: any) => {
  return getComponentType(column.component)
}

const rules = computed(() => {
  return props.addParams.reduce((acc, column) => {
    if (column.required) {
      acc[column.prop] = [{ required: true, message: `${column.label}是必填项`, trigger: 'blur' }]
      if (column.rule) {
        acc[column.prop].push(column.rule)
      }
    }
    return acc
  }, {} as any)
})

const closeDialog = () => {
  visible.value = false
}

const submitForm = () => {
  formRef.value.validate((valid: boolean) => {
    if (valid) {
      emit('submit', form.value)
      visible.value = false
      console.log('Form submitted:', form.value) // 增加调试打印
    } else {
      console.log('表单验证失败')
      return false
    }
  })
}
</script>

<style scoped>
.el-dialog__body .el-form:not(.el-form--inline):not(.el-form--label-top) .el-form-item:last-child {
  margin-bottom: 15px;
}
.el-input-number {
  width: 100%;
}
</style>
